package org.example;

import com.alibaba.fastjson2.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import org.example.entity.ChatHistory;
import org.example.entity.Report;
import org.example.mapper.ChatHistoryMapper;
import org.example.mapper.ReportMapper;
import org.example.model.AssessmentReport;
import org.springframework.ai.chat.client.ChatClient;
import org.springframework.ai.chat.messages.Message;
import org.springframework.ai.chat.model.ToolContext;
import org.springframework.ai.chat.prompt.Prompt;
import org.springframework.ai.chat.prompt.PromptTemplate;
import org.springframework.ai.converter.BeanOutputConverter;
import org.springframework.ai.tool.annotation.Tool;
import org.springframework.ai.tool.annotation.ToolParam;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.ParameterizedTypeReference;
import org.springframework.stereotype.Service;

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.*;

/**
 * 报告结果服务类 - 用于处理评估报告结果的存储、查询和处理
 *
 * @Service注解将其标记为Spring服务组件，使其可被自动扫描和注入
 */
@Service // 标记为Spring服务组件
public class ReportResultService {
    // 默认文件存储路径
    private static final String DEFAULT_FILE_PATH = "reports/";
    private static final String host = "http://localhost:5173";
    @Autowired private ChatClient chatClient;

    @Autowired ReportMapper reportMapper;

    @Autowired ChatHistoryMapper chatHistoryMapper;

    // 用于生成完整的文件下载链接
    public String getFileDownloadUrl(String reportName) {
        return host + "/ai/report/" + reportName;
    }

    public AssessmentReport generateAssessmentReport(String prompt) {
        String promptStr = "请将下面的报告详情转为JSON格式输出\n" + prompt + "\n {format}";
        BeanOutputConverter<AssessmentReport> beanOutputConverter =
                new BeanOutputConverter<>(new ParameterizedTypeReference<AssessmentReport>() {});
        ;
        Message userMessage =
                new PromptTemplate(promptStr)
                        .createMessage(Map.of("format", beanOutputConverter.getFormat()));
        return chatClient
                .prompt(new Prompt(userMessage))
                .call()
                .entity(new ParameterizedTypeReference<AssessmentReport>() {});
    }

    /**
     * 将JSON字符串输出到文件并返回文件名
     *
     * @param jsonString 要输出的JSON字符串
     * @return 生成的文件名
     * @throws IOException 当写入文件失败时抛出
     */
    @Tool(description = "对用户的报告评价的详细内容（包括得分和评语）进行保存，并返回网页报告的地址链接，供用户查看")
    public String generateEvaluationToReport(
            @ToolParam(description = "评估结果报告内容") String assessmentReportStr,
            ToolContext toolContext)
            throws IOException {
        AssessmentReport assessmentReport = generateAssessmentReport(assessmentReportStr);
        // 生成唯一文件名：时间戳_随机UUID.json
        String timestamp =
                LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyyMMddHHmmss"));
        String randomId = UUID.randomUUID().toString().substring(0, 8);
        String fileName = String.format("report_%s_%s", timestamp, randomId);

        //        // 创建目录（如果不存在）
        //        File directory = new File(DEFAULT_FILE_PATH);
        //        if (!directory.exists()) {
        //            directory.mkdirs();
        //        }
        //
        //        // 完整文件路径
        //        String filePath = DEFAULT_FILE_PATH + fileName + ".json";
        //
        //        // 写入文件
        //        try (BufferedWriter writer = new BufferedWriter(new FileWriter(filePath))) {
        //            writer.write(JSONObject.toJSONString(assessmentReport));
        //        }

        Report report = new Report();

        report.setId(fileName);
        report.setConversationId(toolContext.getContext().get("conversationId").toString());
        report.setDetail(JSONObject.toJSONString(assessmentReport));
        report.setCreateTime(new Date());
        reportMapper.insert(report);

        // 返回生成的文件下载链接
        return getFileDownloadUrl(fileName);
    }

    /**
     * 将JSON字符串输出到指定路径的文件并返回文件名
     *
     * @param jsonString 要输出的JSON字符串
     * @param customPath 自定义文件存储路径
     * @return 生成的文件名
     * @throws IOException 当写入文件失败时抛出
     */
    public String writeJsonToFile(String jsonString, String customPath) throws IOException {
        // 生成唯一文件名：时间戳_随机UUID.json
        String timestamp =
                LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyyMMddHHmmss"));
        String randomId = UUID.randomUUID().toString().substring(0, 8);
        String fileName = String.format("report_%s_%s.json", timestamp, randomId);

        // 创建目录（如果不存在）
        File directory = new File(customPath);
        if (!directory.exists()) {
            directory.mkdirs();
        }

        // 确保路径以斜杠结尾
        String path = customPath.endsWith("/") ? customPath : customPath + "/";
        String filePath = path + fileName;

        // 写入文件
        try (BufferedWriter writer = new BufferedWriter(new FileWriter(filePath))) {
            writer.write(jsonString);
        }

        // 返回生成的文件名
        return fileName;
    }

    /**
     * 根据JSON文件名返回文件中的JSON内容
     *
     * @param fileName JSON文件名
     * @return JSON文件内容
     * @throws IOException           当读取文件失败时抛出
     * @throws FileNotFoundException 当文件不存在时抛出
     */
    public String readJsonFromFile(String fileName) throws IOException {
        // 完整文件路径
        String filePath = DEFAULT_FILE_PATH + fileName;
        File file = new File(filePath);

        // 检查文件是否存在
        if (!file.exists()) {
            throw new FileNotFoundException("JSON文件不存在: " + fileName);
        }

        // 读取文件内容
        StringBuilder content = new StringBuilder();
        try (BufferedReader reader = new BufferedReader(new FileReader(file))) {
            String line;
            while ((line = reader.readLine()) != null) {
                content.append(line);
            }
        }

        return content.toString();
    }

    public Report readJsonFromDb(String conversationId) {
        Report report = reportMapper.selectById(conversationId);
        if (report == null) {
            return null;
        }
        List<ChatHistory> historyList =
                chatHistoryMapper.selectList(
                        new QueryWrapper<ChatHistory>()
                                .eq("conversation_id", report.getConversationId())
                                .orderByAsc("\"timestamp\""));
        report.setChatHistoryList(historyList);
        return report;
    }

    /**
     * 从指定路径根据JSON文件名返回文件中的JSON内容
     *
     * @param fileName   JSON文件名
     * @param customPath 自定义文件存储路径
     * @return JSON文件内容
     * @throws IOException           当读取文件失败时抛出
     * @throws FileNotFoundException 当文件不存在时抛出
     */
    public String readJsonFromFile(String fileName, String customPath) throws IOException {
        // 确保路径以斜杠结尾
        String path = customPath.endsWith("/") ? customPath : customPath + "/";
        String filePath = path + fileName;
        File file = new File(filePath);

        // 检查文件是否存在
        if (!file.exists()) {
            throw new FileNotFoundException("JSON文件不存在: " + fileName);
        }

        // 读取文件内容
        StringBuilder content = new StringBuilder();
        try (BufferedReader reader = new BufferedReader(new FileReader(file))) {
            String line;
            while ((line = reader.readLine()) != null) {
                content.append(line);
            }
        }

        return content.toString();
    }

    public List<Report> listReport() {
        List<Report> reportList =
                reportMapper.selectList(new QueryWrapper<Report>().orderByDesc("create_time"));
        reportList.forEach(
                report -> {
                    List<ChatHistory> historyList =
                            chatHistoryMapper.selectList(
                                    new QueryWrapper<ChatHistory>()
                                            .eq("conversation_id", report.getConversationId())
                                            .orderByAsc("\"timestamp\""));
                    report.setChatHistoryList(historyList);
                });
        return reportList;
    }
}
